trigger trg_Request on Request__c (before insert, after insert ,before update, after update) 
{

    if(Trigger.isbefore && Trigger.isInsert)
    {
        for(Request__c serviceLetterObject : Trigger.New)
        {
            serviceLetterObject.isNew__c = true;
        }
    }
    // the creation of an SLA for the Service Letter
    if(Trigger.isInsert && Trigger.isAfter )
    {
        List<SLA__c> slaList = new List<SLA__c>();
        List<Request__c> serviceLetterList = new List<Request__c>();
        Map<string,integer> serviceLetterCustomSettingMap = new Map<string,integer>();
        
        integer slaHours = 0;
        boolean slaFlag = false;
       
        for(SLA_Custom_Setting__c slaRecord : SLA_Custom_Setting__c.getAll().values())
        {
            if(slaRecord.Process_Type__c == 'Service Letter')
            {
                serviceLetterCustomSettingMap.put(slaRecord.Application_Type__c , integer.valueof(slaRecord.SLA_Hours__c));
            }
        }
       System.debug('The Custom Setting : '+ serviceLetterCustomSettingMap.size() ); 
       //if(serviceLetterCustomSettingMap.size() > 0)
       //{
           // Assumes the BSC work hours are the default for the Org
           List<BusinessHours> businessHoursObjectList = new List<BusinessHours>([select id from businesshours where isDefault = true LIMIT 1]) ;
           System.debug('The Business Hour : '+ businessHoursObjectList.size() );  
           if(businessHoursObjectList.size() > 0)
           {
               for(Request__c serviceLetterObject : Trigger.New)
               {
                   System.debug('The Service Letter ID : '+ serviceLetterObject.Id);
                   SLA__c slaObject = new SLA__c();
                   string transactionType = '';
                   if (serviceLetterObject.Transaction_Type_Text__c.contains('Letter - '))
                   {
                       transactionType = serviceLetterObject.Transaction_Type_Text__c.removeStart('Letter - ');
                   }
                   else 
                   {
                       transactionType = serviceLetterObject.Transaction_Type_Text__c;
                   }
                   slaObject.SLA_Hours__c = serviceLetterCustomSettingMap.get(transactionType) ;
                   slaObject.Actual_Start_Date_Time__c = DateTime.Now();
                    
                  
                   // BSC works 11.5 hours / day (8:00 AM - 7:30 PM, M-F). Our SLA is 2-days (23 business hours)
                   System.debug('The Actual Start Time => '+ slaObject.Actual_Start_Date_Time__c );
                   System.debug('The Expected End Date => '+ slaObject.Actual_Start_Date_Time__c.addhours(slaHours));
                   System.debug('The Business Hour Date => ' + BusinessHours.add(businessHoursObjectList[0].id, slaObject.Actual_Start_Date_Time__c, slaHours * 60 * 60 * 1000L));
                   System.debug('The Business Hour Date GMT => ' + BusinessHours.addGmt(businessHoursObjectList[0].id, slaObject.Actual_Start_Date_Time__c, slaHours  * 60 * 60 * 1000L));
                   slaObject.Expected_End_Date__c = BusinessHours.addGmt(businessHoursObjectList[0].id, slaObject.Actual_Start_Date_Time__c, slaHours * 60 * 60 * 1000L);           
                   slaObject.Request__c = serviceLetterObject.Id ;
                   slaObject.Process_Type__c = 'Service Letter';
                   slaObject.Application_Type__c = transactionType;
                   //Adding in the List...
                   slaList.add(slaObject);
                   
                   //Now Automate to goes through the approval process...
                   if(serviceLetterObject.Submission_Channel__c == 'Mobile App')
                   {
                       string approvalResult = buttonExecutionClass.submitForBackofficeApproval(serviceLetterObject.Id );
                       
                       System.debug('Approval Result : '+ approvalResult); 
                   } 
                }
                
                
                //Now Upsert the List...
                if(slaList.size() > 0)
                    upsert slaList;
                
                  
            //}
        }
        //PO Added 7/23/2014
        //From MobileAppRequestExtension
         Set<Id> companySetIds = new Set<Id>();
         for(Request__c req : Trigger.New){
            companySetIds.add(req.Company__c);
         }
         List<Share_Ownership__c> shareOwnershipList = [SELECT Id, Company__c, Shareholder__c, Share_Profit__c
                                                                FROM Share_Ownership__c
                                                                WHERE Company__c in:companySetIds];
         List<Share_Ownership_Request__c> ownershipRequestList = new List<Share_Ownership_Request__c>();

        for(Request__c req : Trigger.New){
            if (req.Transaction_Type_Text__c == 'Certificate - Share Certificate' || 
                req.Transaction_Type_Text__c == 'Certificate - Certificate of Good Standing' ||
                req.Transaction_Type_Text__c == 'Certificate - Certificate of Incorporation' ||
                req.Transaction_Type_Text__c == 'Bank Letter - Open Bank Account')
                
                
            {
                                                                
                if (shareOwnershipList != null)
                {
                    for (Share_Ownership__c ownership : shareOwnershipList)
                    {
                        Share_Ownership_Request__c ownershipRequest = new Share_Ownership_Request__c();
                        ownershipRequest.Request_Number__c = req.Id;
                        ownershipRequest.Company__c = ownership.Company__c;
                        ownershipRequest.Shareholder__c = ownership.Shareholder__c;
                        ownershipRequest.Share__c = ownership.Share_Profit__c;
                        
                        ownershipRequestList.add(ownershipRequest);
                    }
                    
                }
            }

        }        
        //end 
       if(ownershipRequestList.size() > 0)
       insert ownershipRequestList;
                
    
    }
    
    
    // cancel the SLA for the Service Letter 
    if(Trigger.isUpdate && Trigger.isBefore )
    {
        for(Request__c serviceLetterObject : Trigger.New)
        {
            //Logic to Start Approval Process once Receipt Issued...
            if(Trigger.oldmap.get(serviceLetterObject.Id).Request_Status__c != serviceLetterObject.Request_Status__c)
            {
                if(serviceLetterObject.Request_Status__c == 'Receipt Issued' || serviceLetterObject.Request_Status__c == 'Approved By Delivery Department User' || serviceLetterObject.Request_Status__c == 'Approved by Back Office Manager' || serviceLetterObject.Request_Status__c == 'Approved by Back Office User') 
                {
                
                    serviceLetterObject.OwnerId = USERINFO.getUserId();
                }
                
            }
        
        }
    
    }
    
    // cancel the SLA for the Service Letter 
    if(Trigger.isUpdate && Trigger.isAfter )
    {
        Set<ID> serviceLetterIds = new Set<ID>();
        //String Check = 'New_SLA';
        map<ID,ID> slaCancelledMap = new Map<ID,ID>(); //service Letter ID Key
        map<ID,ID> slaCompletedMap = new Map<ID,ID>(); //service Letter ID Key
        
        for(Request__c serviceLetterObject : Trigger.New)
        {
            if(Trigger.oldmap.get(serviceLetterObject.Id).Request_Status__c != serviceLetterObject.Request_Status__c)
            {
                if (serviceLetterObject.Request_Status__c == 'Cancelled' ||  serviceLetterObject.Request_Status__c == 'Rejected')
                    slaCancelledMap.put(serviceLetterObject.Id, serviceLetterObject.Id);
                else if (serviceLetterObject.Request_Status__c=='Scheduled for Delivery')
                    slaCompletedMap.put(serviceLetterObject.Id, serviceLetterObject.Id);
            }
            
            //Logic to Start Approval Process once Receipt Issued...
            if(Trigger.oldmap.get(serviceLetterObject.Id).Request_Status__c != serviceLetterObject.Request_Status__c)
            {
                /*if(serviceLetterObject.Request_Status__c == 'Receipt Issued' ||
                  serviceLetterObject.Request_Status__c == 'Approved by Back Office Manager')*/ 
                if(serviceLetterObject.Request_Status__c == 'Approved by Back Office Manager')  
                {
                    //Automate to go through the approval process second step...
                    string approvalResult = buttonExecutionClass.submitForManagerApproval(serviceLetterObject.Id);
                
                }
            
            }
            
            
        }
        
        if(slaCancelledMap.size() > 0 || slaCompletedMap.size() > 0)
        {
            List<SLA__c> slaList = new List<SLA__c>();
            
            for(SLA__c slaObject : [SELECT ID, isCompleted__c, Actual_End_Date_Time__c, Actual_Start_Date_Time__c, Amendment__c, Application_Type__c, Expected_End_Date__c,isCancelled__c, Process_Type__c, SLA_Hours__c, Status__c, Request__c FROM SLA__c where Request__c IN: slaCancelledMap.keyset() OR Request__c IN: slaCompletedMap.keyset() ORDER BY CreatedDate])
            {
                if( slaCancelledMap.get( slaObject.Request__c) != null)
                {
                    //Putting the Actual_End_Date_Time__c End Date of SLA...
                    slaObject.Actual_End_Date_Time__c = DateTime.Now();
                    slaObject.isCancelled__c =true;
                    slaObject.isCompleted__c =false;
                }
                
                if( slaCompletedMap.get( slaObject.Request__c) != null)
                {
                    //Putting the Actual_End_Date_Time__c End Date of SLA...
                    slaObject.Actual_End_Date_Time__c = DateTime.Now();
                    slaObject.isCancelled__c = false;
                    slaObject.isCompleted__c = true;                    
                }
                
                //Adding in the List...
                slaList.add(slaObject);            
            }        
            
            //Upserting the SLA List...
            if(slaList.size() > 0)
                upsert slaList;
        
        }
     }
}